import json
from collections import defaultdict


class Reqparser:
    @staticmethod
    def dfs(body, path: str, ans: dict, headers: bool = False):
        if isinstance(body, list):
            for i, elem in enumerate(body):
                c_path = f"{path}.{i}"
                Reqparser.dfs(elem, c_path, ans, headers)

        elif isinstance(body, dict):
            if not body:  # 如果字典为空，则将其作为值添加到结果中
                ans[path].append({})
            else:
                for k, v in body.items():
                    c_path = f"{path}.{k}"
                    Reqparser.dfs(v, c_path, ans, headers)

        else:
            if not headers:
                if isinstance(body, bool):
                    ans[str(body)].append(path)
                else:
                    if isinstance(body, int):
                        body=str(body)+'originint'#值是数字类型
                    ans[body].append(path)
    @staticmethod
    def get_result(body, headers=False):
        ans = defaultdict(list)
        Reqparser.dfs(body, 'request', ans, headers)
        return ans
    @staticmethod
    def search_string(str_list, list):
        # 查询是否包含str
        # 在上述代码中，我们使用了两个嵌套的列表推导式。
        # 外层的列表推导式遍历str_list中的每个字符串，
        # 内层的列表推导式遍历my_list中的每个项。在内层的列表推导式中，我们使用any()
        # 函数来检查当前字符串是否在my_list的任意项中。最终，all()
        # 函数会检查外层的列表推导式，如果所有的值都为True，则返回True，否则返回False。
        return all(any(search_str in item for item in list) for search_str in str_list)
    @staticmethod
    def replace_request(result):
        for k, v in result.items():
            if len(v) > 1 and Reqparser.search_string(['res', 'payload'], v):  # 在payload和res里同时出现

                print('payload是：', k)
                print(v)
                print('------------')
    @staticmethod
    def find_element(path_list: list, request_list, value):
        # 如果first==数字
        # 如果first==数字sameint
        # 如果fitst==字母
        path_list = path_list[1:]
        if len(path_list) == 0:  # 说明是最后一个
            return value
        first = path_list[0]  # 当前的元素
        if first.isdigit():  # 如果是数字  生成一个列表
            index = int(first)
            while len(request_list) <= index:
                request_list.append('')
            if len(path_list) > 1 and path_list[1].isdigit() and request_list[index] == '':  # 如果下一个是数字，说明下一个是列表
                request_list[index] = []
            elif len(path_list) > 1 and request_list[index] == '':
                request_list[index] = {}  # 如果下一个是字符串，说明下一个是字典
            middle = request_list[index]
            request_list[index] = Reqparser.find_element(path_list, middle, value)  # d
        elif first.endswith("sameint") and first.replace("sameint", "").isdigit():  # 列表里面是值

            first = first.replace("sameint", "")
            if first.isdigit():
                index = int(first)

                while len(request_list) <= index:
                    request_list.append('')

                middle = request_list[index]
                request_list[index] = Reqparser.find_element(path_list, middle, value)


        else:
            if len(path_list) > 1 and path_list[1].isdigit() and first not in request_list:
                request_list[first] = []

            elif len(path_list) > 1 and path_list[1].rstrip("sameint").isdigit() \
                    and first not in request_list:  # 如果下一个是数字--下一个是列表
                request_list[first] = []
            elif first not in request_list:  # 下一个是字典
                if first.endswith("sameint"):
                    first = first.replace("sameint", "")
                request_list[first] = {}
            # print("first是",first)
            middle = request_list[first]
            request_list[first] = Reqparser.find_element(path_list, middle, value)

        return request_list
    @staticmethod
    def find_same_key(dict: dict, substring: str):  # 第一步和第二部
        substring_list = []
        for key, value in dict.items():
            if isinstance(key, str):

                if substring in key:  # 查找包含originint的key
                    substring_list.append({key.replace("originint", ""): value})  # 把这些key放到新的列表里
        # print(substring_list)
        for key_dict in substring_list:  # 在新的列表里轮询字典
            for k, v in key_dict.items():  # 查看是否在老的字典里有相同的值
                if k in dict:  # 如果有
                    # print(key_dict.values())                                 #
                    new_values = [s + "sameint" for s in v]
                    dict[k].extend(new_values)
                    dict[k] = Reqparser.sort_list(dict[k])
                    dict.pop(k + "originint")
        return dict
    @staticmethod
    def sort_list(list):
        my_list = [element.replace('request.', '') for element in list]

        def custom_sort_key(element):
            # 提取数字部分
            num = int(element.split('.')[0])
            # 判断是否以 "payload" 开头
            is_payload = element.split('.')[1] == 'payload'
            # 返回一个元组，按照要求进行排序
            return (num, not is_payload)

        my_list.sort(key=custom_sort_key)
        my_list = ['request.' + element for element in my_list]

        return my_list
    @staticmethod
    def reverse_dfs(result, request_list):
        for k, v in result.items():  # "value":[path_list]
            if isinstance(k, str) and k.lower() in ['true', 'false']:
                k = k.lower() == 'true'
            for path in v:  # [path1,path2]
                if Reqparser.search_string(['res', 'payload'], v):  # 找出在payload和res里同时出现的数据
                    path_list = path.split('.')
                    # request_list = find_element(path_list, request_list, k)
                    if v.index(path) != 0:
                        if isinstance(k, str) and k.endswith('originint'):

                            k = v[0].replace("request", "$") + 'originint'  # 如果不是第一个路径，那就全都替换成第一个路径
                        else:
                            k = v[0].replace("request", "$")  # 如果不是第一个路径，那就全都替换成第一个路径
                # elif isinstance(path, str) and path.endswith("headers"):
                elif Reqparser.search_string(['headers'], v):
                    path_list = path.split('.')

                    if v.index(path) != 0:
                        k = v[0].replace("request", "$")
                elif len(v) > 1:
                    path_list = path.split('.')


                else:  # 说明只有一个值
                    if len(path) == 0:  # 说明只有一个空字典
                        if not isinstance(k, bool):
                            path_list = k.split('.')
                        request_list = Reqparser.find_element(path_list, request_list, {})
                        break
                    path_list = path.split('.')

                request_list = Reqparser.find_element(path_list, request_list, k)

        return request_list

    @classmethod
    def make_script(self,reqlist):
        print("reqlist",reqlist)
        list_empty = []
        for req in reqlist:
            del req["index"]
            del req["create_time"]
            del req["update_time"]
        path_list = self.get_result(reqlist)


        same_list = self.find_same_key(path_list, "originint")

        reverse_dfs_list = self.reverse_dfs(same_list, list_empty)


        index = 1
        for scr in reverse_dfs_list:
            scr["index"] = index
            index+=1
        return reverse_dfs_list
if __name__ == '__main__':

    req2 = [{"res":"ss","payload":"ss","index":1,"create_time":1,"update_time":1},{"res":"ss","index":1,"create_time":1,"update_time":1}]
    reqparser = Reqparser()
    print(reqparser.make_script(req2))
